package com.lf.mykotlin.keyword

import android.view.View
import android.widget.Button

/**
 * @date: 2023/5/11
 */

/*
    kotlin中有一个重要的关键字object，其主要使用场景有以下三种：
        1. 对象表达式（Object Expression）
        2. 伴生对象（Companion Object）
        3. 对象声明（Object Expression）
 */

/**
 *  1. 对象表达式
 *      对象表达式用于生成匿名类的对象，该匿名类可以直接从零开始创建，也可以继承自某一父类，或者实现某一接口
 */
class OuterObjExpression {
    private val objExpression = object {
        fun objExpressionPrint() {
            println("objExpressionPrint")
        }
    }
}

interface CallBack {
    fun onSuccess()
    fun onFailure()
}

fun testObjectEx() {
     val callBack = object : CallBack {

        override fun onSuccess() {}

        override fun onFailure() {}
    }
    val btn : Button

    // 通过对象表达式实现点击事件回调
//    btn.setOnClickListener(object : View.OnClickListener {
//        override fun onClick(v: View) {
//
//        }
//    })
}


/**
 * 2. 伴生对象
 *      因为在kotlin中是没有static关键字的，也就意味着没有静态方法和静态成员。
 *      那么在kotlin中如果想要表达这种概念，可以使用
 *          包级别函数（package-level funcation）
 *          伴生对象（companion object）。

 *      这两者的区别是伴生对象可以直接访问其外部类中私有成员，而包级别函数不行
 *
 *
 *     伴生对象语法形式:
 *      class ClassName {
            // 伴生对象名可以省略，默认为Companion
            companion object 伴生对象名 {
                // define field and method
            }
        }

        kotlin代码调用：App.getAppContext()
        java代码调用：App.Companion.getAppContext();
 */

class App {
    companion object AppInner {
        fun getAppContext() {}
    }
}


// 使用伴生对象
fun testCompanion() {
    App.getAppContext()   //推荐
    App.AppInner.getAppContext()

    val a1 = App
    val a2 = App.AppInner
}


/**
 * 3. 对象声明
 *      对象声明是为了更好的声明单例模式。对象声明并非一个表达式，因此其不能放在赋值语句的右侧
 *
 *      kotlin代码调用：UserManager.saveUser()
        java代码调用：UserManager.INSTANCE.saveUser();
 */
object UserManager {

    public val name = "zhangsan"

    fun saveUser() {
        println("objDeclarationPrint")
    }
}

// 使用单例
fun testObjectDec() {
    UserManager.saveUser()
    UserManager.name
}




